Introduce HKDF to PKCS11 TA - #7837
Conversation
|
Please provide a proper commit message. |
| PKCS11_CKM_SHA512_RSA_PKCS_PSS = 0x00045, | ||
| PKCS11_CKM_SHA224_RSA_PKCS = 0x00046, | ||
| PKCS11_CKM_SHA224_RSA_PKCS_PSS = 0x00047, | ||
| PKCS11_CKM_HKDF_DERIVE = 0x0402a, |
There was a problem hiding this comment.
I'd prefer we keep on sorting enum labels per value. Could you move PKCS11_CKM_HKDF_DERIVE down to the end of the enum list?
| PKCS11_CKM_UNDEFINED_ID = PKCS11_UNDEFINED_ID, | ||
| }; | ||
|
|
||
| /* HKDF salt source selectors (mirror libckteec CKF_HKDF_SALT_*) */ |
There was a problem hiding this comment.
Suggestion, for consistency with other inlie descriptions
| /* HKDF salt source selectors (mirror libckteec CKF_HKDF_SALT_*) */ | |
| /* | |
| * Valid values for HKDF source selectors | |
| * PKCS11_CKF_HKDF_SALT_<x> reflects CryptoKi client API IDs CKF_HKDF_SALT_<x>. | |
| */ |
| if (key_class != PKCS11_CKO_SECRET_KEY || | ||
| key_type != PKCS11_CKK_GENERIC_SECRET) | ||
| return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED; | ||
| break; |
There was a problem hiding this comment.
Could you add an empty line below, for conssitency.
| } else if (processing_is_tee_hkdf(proc_params->id)) { | ||
| if (function != PKCS11_FUNCTION_DERIVE) { | ||
| rc = PKCS11_CKR_MECHANISM_INVALID; | ||
| goto out; |
There was a problem hiding this comment.
If function != PKCS11_FUNCTION_DERIVE I think we should not have reached this point.
TEE_Panic(function) could apply.
IMHO ASSERT(function != PKCS11_FUNCTION_DERIVE) could be enough.
There was a problem hiding this comment.
I picked TEE_Panic(function) for consistency
| } | ||
|
|
||
| /* Mirrors the strict GP HMAC type ranges from core/tee/tee_svc_cryp.c */ | ||
| struct hkdf_prf { |
There was a problem hiding this comment.
Prefer have struct defined before any fucntion: here, before processing_is_tee_hkdf() definition.
| TA_MECHANISM(PKCS11_CKM_AES_ECB_ENCRYPT_DATA, PKCS11_CKFM_DERIVE), | ||
| TA_MECHANISM(PKCS11_CKM_AES_CBC_ENCRYPT_DATA, PKCS11_CKFM_DERIVE), | ||
| TA_MECHANISM(PKCS11_CKM_ECDH1_DERIVE, PKCS11_CKFM_DERIVE), | ||
| TA_MECHANISM(PKCS11_CKM_HKDF_DERIVE, PKCS11_CKFM_DERIVE), |
There was a problem hiding this comment.
Prefer adding this line at the end of the array, for consistency with pkcs11_modes[].
| if (rc) | ||
| return rc; | ||
| } else { | ||
| *salt = NULL; |
There was a problem hiding this comment.
Could remove *salt = NULL (also *info = NULL below) since we known these are already zero initialiaze.
| salt = NULL; | ||
| salt_len = 0; |
There was a problem hiding this comment.
IMO it would be worth be strict on expected parameters provided by the client:
| salt = NULL; | |
| salt_len = 0; | |
| if (salt || salt_len) | |
| rc = PKCS11_CKR_MECHANISM_PARAM_INVALID; |
| if (!salt_obj) { | ||
| rc = PKCS11_CKR_KEY_HANDLE_INVALID; | ||
| goto out; | ||
| } |
There was a problem hiding this comment.
Should check access to salt key handle.
rc = check_access_attrs_against_token(session, salt_obj->attributes);
if (rc)
goto out;
| res = TEE_ERROR_GENERIC; | ||
|
|
||
| out: | ||
| memset(padded_key, 0, sizeof(padded_key)); |
|
I forgot to thank you for these additions. I'll need to take a few other looks, for the details, but the overall LGTM. |
@etienne-lms , happy to contribute, thank you for the review, I have updated the branch. |
|
This pull request has been marked as a stale pull request because it has been open (more than) 30 days with no activity. Remove the stale label or add a comment, otherwise this pull request will automatically be closed in 5 days. Note, that you can always re-open a closed issue at any time. |
|
Keep alive. |
etienne-lms
left a comment
There was a problem hiding this comment.
For commit "core: tee: tee_svc_cryp: default TEE_ALG_HKDF hash to SHA-256" and
commit "libutee: tee_api_operations: accept TEE_ALG_HKDF in TEE_AllocateOperation":
Look consistent to me.
Reviewed-by: Etienne Carriere <etienne.carriere@st.com>
For commit "ta: pkcs11: Introduce HKDF_DERIVE support", some minor comments. The overall looks good to me but I need another review.
My apologies for this late feedback on your P-R. Thanks for your patience.
| if (function != PKCS11_FUNCTION_DERIVE) { | ||
| TEE_Panic(function); | ||
| } |
There was a problem hiding this comment.
For consistency, prefer without braces for single line conditioned instructions:
| if (function != PKCS11_FUNCTION_DERIVE) { | |
| TEE_Panic(function); | |
| } | |
| if (function != PKCS11_FUNCTION_DERIVE) | |
| TEE_Panic(function); |
| memzero_explicit(okm, out_byte_size); | ||
| TEE_Free(okm); | ||
| } | ||
| release_active_processing(session); |
There was a problem hiding this comment.
release_active_processing() is already called from entry_processing_key(). For consistency I'd prefer you remove this line.
| if (!rc) | ||
| goto done; | ||
| goto out; |
There was a problem hiding this comment.
For consistency with the other cases in this function, prefer the other way round:
| if (!rc) | |
| goto done; | |
| goto out; | |
| if (rc) | |
| goto out; | |
| goto done; |
| if (key_obj != TEE_HANDLE_NULL) | ||
| TEE_FreeTransientObject(key_obj); | ||
| if (op != TEE_HANDLE_NULL) | ||
| TEE_FreeOperation(op); |
There was a problem hiding this comment.
Could remove the tests:
| if (key_obj != TEE_HANDLE_NULL) | |
| TEE_FreeTransientObject(key_obj); | |
| if (op != TEE_HANDLE_NULL) | |
| TEE_FreeOperation(op); | |
| TEE_FreeTransientObject(key_obj); | |
| TEE_FreeOperation(op); |
| case PKCS11_CKF_HKDF_SALT_KEY: { | ||
| struct pkcs11_object *salt_obj = NULL; | ||
| void *salt_value = NULL; | ||
| uint32_t salt_value_size = 0; |
There was a problem hiding this comment.
The braces added here make indentation a bit strange. I'd prefer you move the local variable at function entry or use a local helper function for the salt key case.
|
@etienne-lms , I appreciate your review, I have updated the branch with your suggestions. |
etienne-lms
left a comment
There was a problem hiding this comment.
Still LGTM. See the remaining comments.
| rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &out_byte_size); | ||
| if (rc) | ||
| goto out; |
There was a problem hiding this comment.
The specs says generated object template may not specify CKA_VALUE_LEN when bExpand is false, in which case the length is defined by the algo.
Suggestion:
| rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &out_byte_size); | |
| if (rc) | |
| goto out; | |
| rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &out_byte_size); | |
| if (rc) { | |
| /* When bExpand is false, default default lengh is the hash length */ | |
| if (rc != PKCS11_RV_NOT_FOUND) | |
| goto out; | |
| if (expand == PKCS11_TRUE) { | |
| rc = PKCS11_CKR_MECHANISM_PARAM_INVALID; | |
| goto out; | |
| } | |
| out_byte_size = prf.hash_len; | |
| } |
| if (rc) | ||
| goto out; | ||
|
|
||
| switch (salt_type) { |
There was a problem hiding this comment.
Nitpicking: thee spec says the slat should be ignored when bExtract is false. I wonder if a strict implementation should avoid error cases when salt parameters are invalid, like skipping this switch/case sequence when so. What do you think?
There was a problem hiding this comment.
Agreed, always supportive of removing vendor specific failure modes that aren't reflected in the spec!
|
@etienne-lms , addressed comments and tested against OP-TEE/optee_test#819 |
132a173 to
09a85c2
Compare
|
Will add review tags for all commits once I get the thumbs up |
|
@etienne-lms @jenswikl I fixed the workflow errors, still need a maintainer rerun and reviewer tag for the final commit! |
|
For "core: tee: tee_svc_cryp: default TEE_ALG_HKDF hash to SHA-256" and "libutee: tee_api_operations: accept TEE_ALG_HKDF in TEE_AllocateOperation": |
The consolidated TEE_ALG_HKDF carries no hash bits in its algorithm ID. tee_cryp_hkdf() runs the value through TEE_ALG_HASH_ALGO(), so seed hash_id with TEE_ALG_GET_DIGEST_HASH(TEE_ALG_HKDF_SHA256_DERIVE_KEY) rather than TEE_ALG_SHA256 to match that form. Signed-off-by: Hussain Miyaziwala <hussain_miya@hotmail.com> Reviewed-by: Etienne Carriere <etienne.carriere@st.com> Reviewed-by: Jerome Forissier <jerome.forissier@arm.com>
…tion The consolidated TEE_ALG_HKDF identifier was missing from the switch in TEE_AllocateOperation(), so allocating an operation for it returned TEE_ERROR_NOT_SUPPORTED. Add it alongside the per-hash HKDF variants. Signed-off-by: Hussain Miyaziwala <hussain_miya@hotmail.com> Reviewed-by: Etienne Carriere <etienne.carriere@st.com> Reviewed-by: Jerome Forissier <jerome.forissier@arm.com>
Add the PKCS#11 v3.0 CKM_HKDF_DERIVE mechanism. The implementation runs HKDF (RFC 5869) directly on top of TEE_ALG_HMAC_* so that extract-only, expand-only and combined modes are all supported, for any HMAC PRF the GP API offers (MD5, SHA-1, SHA-224/256/384/512). The mechanism parameters follow the wire format produced by libckteec (bExtract, bExpand, prfHashMechanism, salt source/length/data, hSaltKey, info length/data) and the parent key must be a CKO_SECRET_KEY of CKK_GENERIC_SECRET that supplies the IKM. Signed-off-by: Hussain Miyaziwala <hussain_miya@hotmail.com>
09a85c2 to
2e52a12
Compare
This PR implements CKM_HKDF_DERIVE (PKCS#11 v3.0, RFC 5869) in the PKCS#11 TA so that clients can perform HKDF Extract, Expand, or Extract-then-Expand against a generic-secret parent key.
Summary
New ta/pkcs11/src/processing_hkdf.c: HKDF Extract / Expand built directly on TEE_ALG_HMAC_* rather than the GP TEE_ALG_HKDF so all three modes (extract-only, expand-only, both) and any HMAC-supported PRF hash (MD5, SHA-1, SHA-224/256/384/512) can be supported. Short keys are zero-padded to the GP HMAC type minimum (equivalent under RFC 2104) so RFC 5869 test vectors with sub-minimum salts work.
Mechanism plumbing:
Wire format matches libckteec's serialize_mecha_hkdf_derive_param().
Unrelated supporting fix: core/tee/tee_svc_cryp.c and lib/libutee/tee_api_operations.c — TEE_ALG_HKDF (consolidated form, no hash bits in the algo ID) now defaults to SHA-256 in get_hkdf_params() and is accepted by TEE_AllocateOperation(). Without this, an operation for TEE_ALG_HKDF returns TEE_ERROR_NOT_SUPPORTED.
RFC 5869 conformance
Related PRs
Testing